# ManyToManyRelation.java

    package org.codefilarete.stalactite.engine.configurer.model;

    import java.util.Collection;
    import java.util.function.Supplier;
    import javax.annotation.Nullable;

    import org.codefilarete.reflection.ReadWritePropertyAccessPoint;
    import org.codefilarete.stalactite.dsl.property.CascadeOptions.RelationMode;
    import org.codefilarete.stalactite.engine.runtime.AssociationTable;
    import org.codefilarete.stalactite.sql.ddl.structure.Table;
    import org.codefilarete.stalactite.sql.result.BeanRelationFixer;

    public class ManyToManyRelation<
    		SRC, TRGT,
    		S extends Collection<TRGT>,
    		SRCID, TRGTID,
    		LEFTTABLE extends Table<LEFTTABLE>,
    		RIGHTTABLE extends Table<RIGHTTABLE>,
    		ASSOCIATIONTABLE extends AssociationTable<ASSOCIATIONTABLE, LEFTTABLE, RIGHTTABLE, SRCID, TRGTID>>
    		extends ComponentRelation<SRC, TRGT, S, LEFTTABLE, RIGHTTABLE, SRCID> {

    	private final Entity<TRGT, ?, ?> targetEntity;

    	@Nullable
    	private final ReadWritePropertyAccessPoint<SRC, TRGT> mappedByAccessor;

    	public ManyToManyRelation(Entity<TRGT, ?, ?> targetEntity,
    	                          ReadWritePropertyAccessPoint<SRC, S> accessor,
    	                          @Nullable ReadWritePropertyAccessPoint<SRC, TRGT> mappedByAccessor,
    	                          RelationMode relationMode,
    	                          boolean fetchSeparately,
    	                          IntermediaryRelationJoin<LEFTTABLE, RIGHTTABLE, ASSOCIATIONTABLE, SRCID, TRGTID> join,
    	                          BeanRelationFixer<SRC, TRGT> beanRelationFixer,
    	                          Supplier<S> collectionFactory) {
    		super(accessor, relationMode, fetchSeparately, join, beanRelationFixer, collectionFactory);
    		this.targetEntity = targetEntity;
    		this.mappedByAccessor = mappedByAccessor;
    	}

    	public Entity<TRGT, ?, ?> getTargetEntity() {
    		return targetEntity;
    	}

    	@Nullable
    	public ReadWritePropertyAccessPoint<SRC, TRGT> getMappedByAccessor() {
    		return mappedByAccessor;
    	}
    }